package com.onec.service.unsafe.fork;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * fork join 框架
 */
public class AccumulateTask extends RecursiveTask<Integer> {

  private static final Integer THREASIZE = 2000;

  private Integer start;
  private Integer end;

  public AccumulateTask(Integer start, Integer end) {
    this.start = start;
    this.end = end;
  }

  @Override
  protected Integer compute() {
    int sum = 0;
    boolean canCompute = (end - start) <= THREASIZE;
    if (canCompute) {
      //直接计算结果
      for (int i = start; i < end; i++) {
        sum += i;
      }
    } else {
      // fork 子线程执行
      int middle = (start + end) / 2;
      AccumulateTask accumulateTask = new AccumulateTask(start, middle);
      AccumulateTask accumulateTask1 = new AccumulateTask(middle + 1, end);

      accumulateTask.fork();
      accumulateTask1.fork();

      int sum1 = accumulateTask.join();
      int sum2 = accumulateTask1.join();
      sum = sum1 + sum2;
    }
    return sum;
  }

  public static void main(String[] args) throws ExecutionException {
    ForkJoinPool forkJoinPool = new ForkJoinPool();
    AccumulateTask accumulateTask = new AccumulateTask(1, 100);
    Future<Integer> sum = forkJoinPool.submit(accumulateTask);
    int result = 0;
    try {
      result = sum.get(100, TimeUnit.SECONDS);
    } catch (InterruptedException | TimeoutException e) {
      e.printStackTrace();
    }
    System.out.println(result);

  }
}
